<template>
  <lay-layer 
    v-model="visible" 
    :title="title"
    :area="['600px', 'auto']"
    :maxmin="false"
    :resize="false"
    @close="handleClose"
  >
    <div class="category-dialog">
      <lay-form ref="formRef" :model="formData" :rules="formRules" required-error-type="msg">
        <lay-row :space="15">
          <lay-col :span="24">
            <lay-form-item label="分类名称" prop="name">
              <lay-input v-model="formData.name" placeholder="请输入分类名称" />
            </lay-form-item>
          </lay-col>
        </lay-row>

        <lay-row :space="15">
          <lay-col :span="12">
            <lay-form-item label="父分类" prop="parentId">
              <lay-select 
                v-model="formData.parentId" 
                placeholder="请选择父分类"
                :disabled="mode === 'edit' && categoryData?.level === 1"
              >
                <lay-select-option :value="0">顶级分类</lay-select-option>
                <template v-for="option in flatParentOptions" :key="option.id">
                  <lay-select-option 
                    :value="option.id" 
                    :disabled="option.level >= 2"
                  >
                    {{ getOptionLabel(option) }}
                  </lay-select-option>
                </template>
              </lay-select>
            </lay-form-item>
          </lay-col>
          <lay-col :span="12">
            <lay-form-item label="排序" prop="sortOrder">
              <lay-input-number 
                v-model="formData.sortOrder" 
                :min="0" 
                :max="9999"
                placeholder="排序值"
              />
            </lay-form-item>
          </lay-col>
        </lay-row>

        <lay-row :space="15">
          <lay-col :span="12">
            <lay-form-item label="分类图标" prop="icon">
              <lay-input v-model="formData.icon" placeholder="请输入图标类名" />
            </lay-form-item>
          </lay-col>
          <lay-col :span="12">
            <lay-form-item label="显示状态" prop="isShow">
              <lay-select v-model="formData.isShow" placeholder="请选择显示状态">
                <lay-select-option :value="1">显示</lay-select-option>
                <lay-select-option :value="0">隐藏</lay-select-option>
              </lay-select>
            </lay-form-item>
          </lay-col>
        </lay-row>

        <lay-row :space="15">
          <lay-col :span="24">
            <lay-form-item label="分类图片" prop="image">
              <div class="image-upload-container">
                <div v-if="formData.image" class="image-preview">
                  <img :src="formData.image" alt="分类图片" />
                  <div class="image-overlay">
                    <lay-icon type="layui-icon-delete" @click="removeImage" />
                  </div>
                </div>
                <div v-else class="image-upload" @click="handleImageUpload">
                  <lay-icon type="layui-icon-add-1" />
                  <div>点击上传图片</div>
                </div>
                <input 
                  ref="fileInputRef" 
                  type="file" 
                  accept="image/*" 
                  style="display: none;" 
                  @change="handleFileChange"
                />
              </div>
            </lay-form-item>
          </lay-col>
        </lay-row>

        <lay-row :space="15">
          <lay-col :span="24">
            <lay-form-item label="分类描述" prop="description">
              <lay-textarea 
                v-model="formData.description" 
                placeholder="请输入分类描述"
                :rows="3"
              />
            </lay-form-item>
          </lay-col>
        </lay-row>
      </lay-form>

      <div class="dialog-footer">
        <lay-button @click="handleClose">取消</lay-button>
        <lay-button type="primary" :loading="submitting" @click="handleSubmit">
          {{ submitting ? '提交中...' : '确定' }}
        </lay-button>
      </div>
    </div>
  </lay-layer>
</template>

<script setup lang="ts">
import { ref, reactive, computed, watch, nextTick } from 'vue'
import { layer } from '@layui/layui-vue'
import { CategoryApi, type Category } from '../../../../api/module/category'
import { UploadApi } from '../../../../api/module/upload'

// 定义Props
interface Props {
  modelValue: boolean
  mode: 'create' | 'edit'
  categoryData?: Category
  parentOptions: Category[]
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: false,
  mode: 'create',
  categoryData: undefined,
  parentOptions: () => []
})

// 定义emits
const emit = defineEmits<{
  'update:modelValue': [value: boolean]
  'success': []
}>()

// 响应式数据
const formRef = ref()
const fileInputRef = ref()
const submitting = ref(false)

// 表单数据
const formData = reactive<Category>({
  name: '',
  parentId: 0,
  level: 1,
  sortOrder: 0,
  icon: '',
  image: '',
  description: '',
  isShow: 1
})

// 表单验证规则
const formRules = {
  name: [
    { required: true, message: '请输入分类名称', trigger: 'blur' },
    { min: 1, max: 100, message: '分类名称长度必须在1-100个字符之间', trigger: 'blur' }
  ],
  parentId: [
    { required: true, message: '请选择父分类', trigger: 'change' }
  ],
  sortOrder: [
    { required: true, message: '请输入排序值', trigger: 'blur' }
  ],
  isShow: [
    { required: true, message: '请选择显示状态', trigger: 'change' }
  ]
}

// 计算属性
const visible = computed({
  get: () => props.modelValue,
  set: (value) => emit('update:modelValue', value)
})

const title = computed(() => {
  return props.mode === 'create' ? '新增分类' : '编辑分类'
})

const flatParentOptions = computed(() => {
  const flatten = (categories: Category[], level = 0): Category[] => {
    let result: Category[] = []
    for (const category of categories) {
      result.push({ ...category, level: level + 1 })
      if (category.children && category.children.length > 0) {
        result = result.concat(flatten(category.children, level + 1))
      }
    }
    return result
  }
  return flatten(props.parentOptions)
})

// 方法
const getOptionLabel = (option: Category) => {
  const prefix = '　'.repeat((option.level - 1) * 2)
  return `${prefix}${option.name}`
}

const handleImageUpload = () => {
  fileInputRef.value?.click()
}

const handleFileChange = async (event: Event) => {
  const target = event.target as HTMLInputElement
  const file = target.files?.[0]
  
  if (!file) return
  
  // 验证文件类型
  if (!file.type.startsWith('image/')) {
    layer.msg('请选择图片文件', { icon: 2 })
    return
  }
  
  // 验证文件大小（2MB）
  if (file.size > 2 * 1024 * 1024) {
    layer.msg('图片大小不能超过2MB', { icon: 2 })
    return
  }
  
  try {
    const formData = new FormData()
    formData.append('image', file)
    
    const response = await UploadApi.uploadImage(formData)
    formData.image = response.data.url
    layer.msg('图片上传成功', { icon: 1 })
  } catch (error: any) {
    layer.msg(error.response?.data?.message || '图片上传失败', { icon: 2 })
  }
  
  // 清空input值，允许重复选择同一文件
  target.value = ''
}

const removeImage = () => {
  formData.image = ''
}

const resetForm = () => {
  Object.assign(formData, {
    name: '',
    parentId: 0,
    level: 1,
    sortOrder: 0,
    icon: '',
    image: '',
    description: '',
    isShow: 1
  })
  
  nextTick(() => {
    formRef.value?.clearValidate()
  })
}

const handleClose = () => {
  visible.value = false
  resetForm()
}

const handleSubmit = async () => {
  try {
    const valid = await formRef.value?.validate()
    if (!valid) return
    
    submitting.value = true
    
    // 计算分类级别
    if (formData.parentId === 0) {
      formData.level = 1
    } else {
      const parentCategory = flatParentOptions.value.find(item => item.id === formData.parentId)
      formData.level = parentCategory ? parentCategory.level + 1 : 1
    }
    
    if (props.mode === 'create') {
      await CategoryApi.createCategory(formData)
      layer.msg('创建分类成功', { icon: 1 })
    } else {
      await CategoryApi.updateCategory(props.categoryData!.id!, formData)
      layer.msg('更新分类成功', { icon: 1 })
    }
    
    emit('success')
  } catch (error: any) {
    layer.msg(error.response?.data?.message || '操作失败', { icon: 2 })
  } finally {
    submitting.value = false
  }
}

// 监听器
watch(() => props.modelValue, (newVal) => {
  if (newVal && props.mode === 'edit' && props.categoryData) {
    Object.assign(formData, props.categoryData)
  } else if (newVal && props.mode === 'create' && props.categoryData) {
    // 添加子分类时的预设值
    Object.assign(formData, props.categoryData)
  } else if (newVal && props.mode === 'create') {
    resetForm()
  }
})
</script>

<style scoped>
.category-dialog {
  padding: 20px;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 20px;
  padding-top: 20px;
  border-top: 1px solid #f0f0f0;
}

.image-upload-container {
  width: 120px;
  height: 120px;
  border: 2px dashed #d9d9d9;
  border-radius: 6px;
  position: relative;
  overflow: hidden;
  cursor: pointer;
  transition: border-color 0.3s;
}

.image-upload-container:hover {
  border-color: #1890ff;
}

.image-upload {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  color: #999;
  font-size: 14px;
}

.image-upload .layui-icon {
  font-size: 24px;
  margin-bottom: 8px;
}

.image-preview {
  width: 100%;
  height: 100%;
  position: relative;
}

.image-preview img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.image-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.3s;
  cursor: pointer;
}

.image-preview:hover .image-overlay {
  opacity: 1;
}

.image-overlay .layui-icon {
  color: white;
  font-size: 20px;
}
</style>